package com.corpgovernment.costcenter.controller;

import java.util.List;
import java.util.Map;
import java.util.Set;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.corpgovernment.api.costcenter.model.GetCostCenterListResponse;
import com.corpgovernment.common.base.CommonException;
import com.ctrip.corp.obt.generic.utils.CollectionUtils;
import com.ctrip.corp.obt.generic.utils.JsonUtils;
import lombok.extern.slf4j.Slf4j;
import com.corpgovernment.api.costcenter.model.*;
import com.corpgovernment.common.common.CorpBusinessException;
import com.corpgovernment.costcenter.vo.CostCenterInfoRspVo;
import com.corpgovernment.costcenter.vo.CostCenterInfoVo;
import com.corpgovernment.organization.constant.OrganizationResponseCodeEnum;
import io.swagger.annotations.ApiOperation;
import com.corpgovernment.common.base.CommonException;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import com.corpgovernment.api.costcenter.model.BaseKeyValue;
import com.corpgovernment.api.costcenter.model.CostCenter;
import com.corpgovernment.api.costcenter.model.CostCenterParamValidateRequest;
import com.corpgovernment.api.costcenter.model.CostCenterParamValidateResponse;
import com.corpgovernment.api.costcenter.model.GetCostCenterListRequest;
import com.corpgovernment.api.costcenter.model.GetDepartmentsRequest;
import com.corpgovernment.api.costcenter.model.GetProjectInfoRequest;
import com.corpgovernment.api.costcenter.model.Result;
import com.corpgovernment.api.costcenter.model.SaveOrderCostCenterRequest;
import com.corpgovernment.api.organization.model.project.request.CostcenterRequest;
import com.corpgovernment.api.organization.vo.GetOrgTreeRsp;
import com.corpgovernment.common.base.BaseUserInfo;
import com.corpgovernment.common.base.JSONResult;
import com.corpgovernment.common.common.CorpBusinessException;
import com.corpgovernment.common.operatelog.OperateLog;
import com.corpgovernment.common.operatelog.constant.OperateLogContant;
import com.corpgovernment.costcenter.service.IProjectInfoService;
import com.corpgovernment.costcenter.service.impl.CostCenterServiceImpl;
import com.corpgovernment.costcenter.validator.ParamValidator;
import com.corpgovernment.costcenter.vo.*;
import com.corpgovernment.organization.constant.OrganizationResponseCodeEnum;
import com.ctrip.corp.obt.generic.utils.CollectionUtils;
import com.ctrip.corp.obt.generic.utils.StringUtils;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.List;
import java.util.Map;
import java.util.Set;

@RestController
@Slf4j
@RequestMapping("costcenter")
public class CostCenterController {
    @Autowired
    private CostCenterServiceImpl costCenterServiceImpl;
    @Autowired
    private ParamValidator paramValidator;
    @Autowired
    private IProjectInfoService iProjectInfoService;

    /**
     * 新增成本中心
     *
     * @param request
     * @param userInfo
     * @return
     */
    @RequestMapping("insert")
    @OperateLog(OperateLogContant.COSTINSERT)
    public JSONResult<Integer> insert(@RequestBody CostCenter request, BaseUserInfo userInfo) {
        // 参数校验
        request.setUid(userInfo.getUid());
        request.setUserName(userInfo.getUserName());
        String errorMsg = paramValidator.validCostCenterParam(request);
        if (!StringUtils.isBlank(errorMsg)) {
            throw new CommonException(errorMsg);
        }
        int result = costCenterServiceImpl.insert(request);
        if (result == 2) {
            throw new CorpBusinessException(OrganizationResponseCodeEnum.COST_CENTER_IS_NULL);
        }
        if (result == 0) {
            return JSONResult.errorMsg(String.format("您输入的成本中心编码%s已存在", request.getCostCenterCode()));
        } else {
            return JSONResult.success(result);
        }
    }

    /**
     * 删除成本中心
     *
     * @param vo
     * @param userInfo
     * @return
     */
    @RequestMapping("delete")
    @OperateLog(OperateLogContant.COSTDELETE)
    public JSONResult delete(@RequestBody Map vo, BaseUserInfo userInfo) {

        vo.put("uId", userInfo.getUid());
        vo.put("userName", userInfo.getUserName());
        if (vo.get("id") == null || vo.get("id").toString().equals("")) {
            return JSONResult.errorMsg("成本中心记录id不能为空");
        }

        int result = costCenterServiceImpl.delete(vo);
        if (result == 2) {
            return JSONResult.errorMsg("该成本中心不存在");
        } else {
            return result > 0 ? JSONResult.success(new Result()) : JSONResult.errorMsg("删除0条");
        }
    }

    /**
     * 修改成本中心
     *
     * @param vo
     * @param userInfo
     * @return
     */
    @RequestMapping("update")
    @OperateLog(OperateLogContant.COSTUPDATE)
    public JSONResult update(@RequestBody CostCenter vo, BaseUserInfo userInfo) {
        if (StringUtils.isBlank(vo.getUid())) {
            vo.setUid(userInfo.getUid());
        }
        if (StringUtils.isBlank(vo.getUserName())) {
            vo.setUserName(userInfo.getUserName());
        }
        // id校验
        if (vo.getId() == null || vo.getId().toString().equals("")) {
            return JSONResult.errorMsg("成本中心记录id不能为空");
        }
        // 参数校验
        String errorMsg = paramValidator.validCostCenterParam(vo);
        if (!StringUtils.isBlank(errorMsg)) {
            return JSONResult.errorMsg(errorMsg);
        }

        int result = costCenterServiceImpl.update(vo);
        if (result == 2) {
            return JSONResult.errorMsg("该成本中心不存在");
        }
        if (result == 0) {
            return JSONResult.errorMsg(String.format("您输入的成本中心编码%s已存在", vo.getCostCenterCode()));
        } else {
            return JSONResult.success(new Result());
        }
    }

    /**
     * 查询成本中心 含分页
     *
     * @param request
     * @param requestUser
     * @return
     */
    @RequestMapping("queryCostCenterInfos")
    public JSONResult queryCostCenterInfos(@RequestBody GetCostCenterListRequest request,
            HttpServletRequest requestUser) {
        return JSONResult.success(costCenterServiceImpl.queryCostCenterInfos(request));
    }

    /**
     * 模糊查询成本中心编码及名称
     * 仅查询【成本中心名称/项目编码】
     * 返回当前 orgId 下全部成本中心名称与编码
     *
     * @param request
     * @return
     */
    @PostMapping(value = "/queryCostCenterNameCode")
    public JSONResult queryCostCenterNameCode(@RequestBody @Validated GetCostCenterListRequest request) {
        return JSONResult.success(costCenterServiceImpl.queryCostCenterNameCode(request));
    }

    /**
     * 根据组织查询成本中心
     *
     * @param orgId
     * @return
     */
    @RequestMapping("getCostCenter")
    public JSONResult<List<CostCenter>> getCostCenter(@RequestParam("orgId") String orgId) {
        return JSONResult.success(costCenterServiceImpl.getCostCenter(orgId));
    }

    /**
     * 根据组织查询成本中心
     *
     * @param orgIdList
     * @return
     */
    @RequestMapping("getCostCenterList")
    public JSONResult<List<CostCenter>> listCostCenter(@RequestParam("orgIdList") List<String> orgIdList) {
        return JSONResult.success(costCenterServiceImpl.listCostCenter(orgIdList));
    }

    /**
     * 根据组织查询成本中心 新
     *
     * @return
     */
    @RequestMapping("getCostCenterNew")
    public JSONResult<List<CostCenter>> getCostCenterNew(@RequestBody GetCostCenterListRequest request,
            BaseUserInfo userInfo) {
        // 不传使用登录人组织进行查询
        if (StringUtils.isBlank(request.getOrgId())) {
            request.setOrgId(userInfo.getOrgId());
        }
        return JSONResult.success(costCenterServiceImpl.getCostCenterNew(request));
    }

    /**
     * 根据公司查询成本中心
     *
     * @return
     */
    @RequestMapping("getCostCentersByCompanyId")
    public JSONResult getCostCentersByCompanyId(@RequestBody GetProjectInfoRequest request) {
        return JSONResult.success(costCenterServiceImpl.getCostCentersByCompanyId(request));
    }

    /**
     * 根据成本中心编码查询成本中心
     *
     * @param costCenterCode
     * @return
     */
    @RequestMapping("getCostCenterByCode")
    public JSONResult getCostCenterByCode(@RequestParam("costCenterCode") String costCenterCode) {
        return JSONResult.success(costCenterServiceImpl.getCostCenterByCode(costCenterCode));
    }

    /**
     * 根据成本中心编码批量查询成本中心
     *
     * @param costCenterCodeList
     * @return
     */
    @RequestMapping("getCostCenterByCodeList")
    public JSONResult getCostCenterByCodeList(@RequestBody List<String> costCenterCodeList) {
        return JSONResult.success(costCenterServiceImpl.getCostCenterByCodeList(costCenterCodeList));
    }

    /**
     * 获取组织树
     *
     * @param request
     * @return
     */
    @RequestMapping("getDepartments")
    public JSONResult<List<GetOrgTreeRsp>> getDepartments(@RequestBody GetDepartmentsRequest request) {
        // orgId校验
        if (StringUtils.isBlank(request.getOrgId())) {
            return JSONResult.errorMsg("子公司orgId不能为空");
        }
        return new JSONResult(costCenterServiceImpl.getOrgTree(request));
    }

    /**
     * 产线下单查询出差申请单
     *
     * @param saveOrderRequest
     * @return
     */
    @RequestMapping("/getCostCenterForSaveOrder")
    public JSONResult<List<BaseKeyValue>>
            getCostCenterForSaveOrder(@RequestBody SaveOrderCostCenterRequest saveOrderRequest) {
        return JSONResult.success(costCenterServiceImpl.getCostCenterForSaveOrder(saveOrderRequest));
    }

    /**
     * 文件上传
     *
     * @param file
     * @param requestVo
     * @return
     */
    @PostMapping("/syncCostInfoExcel")
    public JSONResult syncCostInfoExcel(@RequestParam("file") MultipartFile file, CostCenterExcelVo requestVo) {
        return JSONResult.success(costCenterServiceImpl.syncCostInfoExcel(file, requestVo));
    }

    /**
     * 查询上传记录
     *
     * @param requestVo
     * @return
     */
    @PostMapping(value = "/selectUploadInfoPage")
    public JSONResult selectUploadInfoPage(@RequestBody CostUploadInfoPageRequestVo requestVo) {
        return JSONResult.success(costCenterServiceImpl.selectUploadInfoPage(requestVo));
    }

    /**
     * 查询错误日志
     *
     * @param requestVo
     * @return
     */
    @PostMapping(value = "/selectUploadDetailInfoPage")
    public JSONResult selectUploadDetailInfoPage(@RequestBody CostUploadInfoPageRequestVo requestVo) {
        return JSONResult.success(costCenterServiceImpl.selectUploadDetailInfoPage(requestVo));
    }

    /**
     * 下载错误文件
     *
     * @param requestVo
     * @param response
     */
    @PostMapping(value = "/downloadUploadInfo")
    public void downloadUploadInfo(@RequestBody CostUploadInfoDownloadRequestVo requestVo,
            HttpServletResponse response) {
        costCenterServiceImpl.downloadUploadInfo(requestVo.getTaskNo(), response);
    }

    /**
     * 下载成本中心内容
     */
    @PostMapping(value = "/downloadCostCenter")
    public void downloadCostCenter(@RequestBody CostUploadInfoDownloadRequestVo requestVo,
            HttpServletResponse response) {
        costCenterServiceImpl.downloadCostCenter(requestVo.getCompanyId(), response);
    }

    @RequestMapping("/getCostCenterOrProject")
    JSONResult<CostCenterParamValidateResponse> getCostCenterOrProject(
        @RequestBody CostCenterParamValidateRequest request) {
        
        if(CollectionUtils.isEmpty(request.getOrgId())){
            log.error("/getCostCenterOrProject，查询的成本中心及项目信息的orgId不能为空");
            throw new CorpBusinessException(OrganizationResponseCodeEnum.COMPANY_IS_NULL);
        }

        if(CollectionUtils.isEmpty(request.getOrgId())){
            throw new CorpBusinessException(OrganizationResponseCodeEnum.COMPANY_IS_NULL);
        }

        // 获得成本中心code和name
        CostCenterParamValidateResponse response = costCenterServiceImpl.getCostCenter(request);
        // 获得项目code和name
        CostCenterParamValidateResponse projectResponse = iProjectInfoService.getProject(request);

        response.setProjectInfoList(projectResponse.getProjectInfoList());
        response.setOrgIdProjectMap(projectResponse.getOrgIdProjectMap());
        response.setOrgIdProjectInfoMap(projectResponse.getOrgIdProjectInfoMap());
        response.setProjectNo(projectResponse.getProjectNo());

        return JSONResult.success(response);
    }

    @PostMapping(value = "/syncSaveCostcenter")
    public JSONResult<Integer> syncSaveCostcenter(@RequestBody CostcenterRequest request) {
        CostCenter costCenter = new CostCenter();
        BeanUtils.copyProperties(request, costCenter);
        BaseUserInfo userInfo = new BaseUserInfo();
        userInfo.setUid(request.getUid());
        userInfo.setUserName(request.getUserName());
        return insert(costCenter, userInfo);
    }

    @PostMapping("/queryCostCenterByOrgScope")
    public JSONResult<GetCostCenterListResponse> queryCostCenterByOrgScope(@RequestBody GetCostCenterListRequest request) {
        return JSONResult.success(costCenterServiceImpl.queryCostCenterByOrgScope(request));
    }

    // TODO: 2023/10/13 一次性解密成本中心名称，后续删除
    @RequestMapping("/updateCostCenterNames")
    public void updateCostCenterNames(@RequestParam("id") String id) {
        costCenterServiceImpl.updateNames(id);
    }

    @PostMapping("/queryCostCenterInfoPage")
    @ApiOperation("查询成本中心分页")
    public JSONResult<CostCenterInfoRspVo> queryCostCenterInfoPage(@RequestBody CostCenterInfoVo request) {
        return JSONResult.success(costCenterServiceImpl.queryCostCenterInfoPage(request));
    }

    @PostMapping("/queryCostCenterListByOrgId")
    @ApiOperation("查询机构id查询部门直挂的公司或者公司成本中心列表")
    public JSONResult<List<CostCenterInfoRspVo.CostCenter>> queryCostCenterListByOrgId(@RequestBody CostCenterInfoVo request) {
        return JSONResult.success(costCenterServiceImpl.queryCostCenterListByOrgId(request));
    }
}
